import { AsyncStorage } from 'react-native'
export default class DataStore {
    /**
     * @description: 保存数据
     * @param {data} 
     * @return: callback
     */
    saveData(url, data, callback) {
        if (!data || !url) return;
        AsyncStorage.setItem(url, JSON.stringify(this._wrapData(data), callback))
    }
    /**
     * @description: 本地获取数据
     * @param {url} 
     * @return: 
     */
    fetchLocalData(url) {
        return new Promise((resolve, rejects) => {
            AsyncStorage.getItem(url, (error, result) => {
                if (!error) {
                    try {
                        resolve(JSON.parse(result))
                    } catch (e) {
                        rejects(e);
                        console.error(error)
                    }
                } else {
                    rejects(error)
                    console.error(error);
                }
            })
        })
    }
    /**
     * @description: 网络获取数据
     * @param {type} 
     * @return: 
     */
    fetchNetData(url) {
        return new Promise((resolve, rejects) => {
            fetch(url)
                .then(res => {
                    if (res.ok) {
                        return res.json();
                    }
                    throw new Error('res not ok')
                })
                .then(res => {
                    this.saveData(url, res)
                    resolve(res);
                })
                .catch((err) => {
                    rejects(err);
                })
        })
    }
    /**
     * @description: 获取数据，优先获取本地的，如果本地没有或者过期则发起网络请求
     * @param {url} 
     * @return:{Promise} 
     */
    fetchData(url) {
        return new Promise((resolve, rejects) => {
            this.fetchLocalData(url)
                .then(wrapData => {
                    if (wrapData && DataStore.checkTimestampValid(wrapData.timestamp)) {
                        resolve(wrapData);
                    } else {
                        this.fetchNetData(url)
                            .then(data => {
                                resolve(this._wrapData(data));
                            }).catch(err => {
                                rejects(err)
                            })
                    }
                }).catch(err => {
                    this.fetchNetData(url).then(data => {
                        resolve(this._wrapData(data))
                    }).catch(err => {
                        rejects(err)
                    })
                })
        })
    }
    /**
     * @description: 检查时间戳是否在有效期内
     * @param {timestamp} 更新时间 
     * @return: {boolean} 
     */
    static checkTimestampValid(timestamp) {
        const currentDate = new Date();
        const targetDate = new Date();
        targetDate.setTime(timestamp);
        if (currentDate.getMonth() !== targetDate.getMonth()) return false;
        if (currentDate.getDate() !== targetDate.getDate()) return false;
        if (currentDate.getHours() - targetDate.getHours() > 1) return false;
        return true;
    }
    /**
     * @description: 时间戳
     * @param {type} 
     * @return: 
     */
    _wrapData(data) {
        return {
            data,
            timestamp: new Date().getTime()
        }
    }
}